home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Utilities / RandomDot 1.0.2 / Random Dot Src ƒ / _c / Main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-27  |  12.1 KB  |  533 lines  |  [TEXT/KAHL]

  1. /* main.c - main file of RandomDot
  2.     by David Phillip Oster October 1994 oster@netcom.com
  3.     for:
  4.     Stuart Inglis singlis@waikato.ac.nz
  5.     Department of Computer Science
  6.     University of Waikato, Hamilton, New Zealand
  7.  */
  8. #include "RandomDotMain.h"
  9. #include "RandomDotRes.h"
  10.  
  11. #include "RandomDotWin.h"
  12. #include "Error.h"
  13. #include "Help.h"
  14. #include "Menu.h"
  15. #include "Utils.h"
  16. #include "ZoomCode.h"
  17. #include <AppleEvents.h>
  18. #include <Folders.h>
  19. #include <GestaltEqu.h>
  20.  
  21.  
  22. #define bDoOpenCommandOnce    (1L << 0)
  23. #define bDoHelpCommandOnce    (1L << 1)
  24. #define bDone                (1L << 2)
  25.  
  26. /* *** globals
  27.  */
  28. StringPtr    emptyS = "\p";
  29. Integer        appResFile = -1;    /* our own resID */
  30. Integer        prefResFile = -1;    /* preferences file resID */
  31. FSSpec        prefSpec;            /* file spec for preferences file */
  32. SysEnvRec    world;
  33.  
  34. /* forward declarations.
  35.  */
  36.  
  37. /* *** local to this file.
  38.  */
  39. static LongInt localEventSelect = 0;
  40.  
  41.  
  42. /* FSSpecFunc - call this with an FSSpecPtr and return an OSErr
  43.  */
  44. typedef OSErr (*FSSpecFunc)(FSSpecPtr);
  45.  
  46. /* BetaExpired - TRUE is later than August 1, 1994
  47. >>>
  48.  */
  49. static Boolean BetaExpired(void){
  50.     return FALSE;
  51. }
  52.  
  53. /* InitPreferences - Initialize the preferences file and connect to it.
  54.  */
  55. static OSErr InitPreferences(void){
  56.     OSErr    errCode;
  57.  
  58.     if(noErr == (errCode = FindFolder(kOnSystemDisk, kPreferencesFolderType, kDontCreateFolder, &prefSpec.vRefNum, &prefSpec.parID))){
  59.         GetIndString(prefSpec.name, kMainStrs, kPrefNameS);
  60.         if(-1 == (prefResFile = FSpOpenResFile(&prefSpec, fsRdWrPerm))){
  61.             localEventSelect |= bDoHelpCommandOnce;
  62.             FSpCreateResFile(&prefSpec, kCreator, kPrefType, NIL);
  63.             if(noErr == (errCode = ResError())){
  64.                 prefResFile = FSpOpenResFile(&prefSpec, fsRdWrPerm);
  65.             }
  66.         }
  67.     }
  68.     return errCode;
  69. }
  70.  
  71. /* MissedAEParameters - 
  72.  */
  73. static OSErr MissedAEParameters(AppleEvent *message){
  74.     DescType typeCode;
  75.     Size actualSize;
  76.     OSErr err;
  77.  
  78.     if(errAEDescNotFound == (err = AEGetAttributePtr(message, keyMissedKeywordAttr, typeWildCard,
  79.             &typeCode, NIL, 0L, &actualSize))){
  80.  
  81.         return noErr;
  82.     }
  83.     return (noErr == err ? errAEEventNotHandled : err);
  84. }
  85.  
  86. /* FSOpenWD - convenience function for opening a wRef
  87.  */
  88. static OSErr FSOpenWD(Integer vRef, LongInt dirId, OSType signature, Integer *wRef){
  89.     WDPBRec    io;
  90.     OSErr    val;
  91.  
  92.     io.ioNamePtr    = NIL;
  93.     io.ioVRefNum    = vRef;
  94.     io.ioWDDirID    = dirId;
  95.     io.ioWDProcID    = signature;
  96.     if(noErr == (val = PBOpenWD(&io, FALSE))){
  97.         *wRef = io.ioVRefNum;
  98.     }
  99.     return val;
  100. }
  101.  
  102. /* DirIDVRefToWRef - given a dirId, vRef pair, return the working ref
  103.  */
  104. static OSErr DirIDVRefToWRef(Integer vRef, LongInt dirID, Integer *wRefp){
  105.     return FSOpenWD(vRef, dirID, 'ERIK', wRefp);
  106. }
  107.  
  108.  
  109. static OSErr OpenPrint(AppleEvent *message, AppleEvent *reply, LongInt refCon, FSSpecFunc f){
  110.     FSSpec        fss;
  111.     AEDescList    docList;
  112.     LongInt        index, itemsInList;
  113.     Size        actualSize;
  114.     AEKeyword    keywd;
  115.     DescType    typeCode;
  116.     OSErr        err;
  117.  
  118.     if((err = AEGetParamDesc(message, keyDirectObject, typeAEList, &docList)) != noErr ||
  119.         (err = MissedAEParameters(message)) != noErr ||
  120.         (err = AECountItems(&docList, &itemsInList)) != noErr){
  121.         return err;
  122.     }
  123.  
  124.     for(index = 1; index <= itemsInList; index++){
  125.         if(noErr != (err = AEGetNthPtr(&docList, index, typeFSS, &keywd, &typeCode,
  126.                     (Ptr)&fss, sizeof(FSSpec), &actualSize))){
  127.             break;
  128.         }
  129.         if(noErr != (err = (*f)(&fss))){
  130.             break;
  131.         }
  132.     }
  133.     return AEDisposeDesc(&docList);
  134. }
  135.  
  136. /* DoOpenApp - We get this if we weren't given any documents.
  137.     Nothing to do for now in RandomDot
  138.  */
  139. static pascal OSErr DoOpenApp(AppleEvent *message, AppleEvent *reply, LongInt refCon){
  140.     OSErr err;
  141.  
  142.     if ((err = MissedAEParameters(message)) != noErr){
  143.         return err;
  144.     }
  145.     return noErr;
  146. }
  147.  
  148. /* RandomDotOpen1 - wrapper for RandomDotOpen when we don't know the script code.
  149.  */
  150. static OSErr RandomDotOpen1(FSSpecPtr fs){
  151.     return TellError(RandomDotOpen(fs, smSystemScript));
  152. }
  153.  
  154. /* DoOpenDoc
  155.  */
  156. static pascal OSErr DoOpenDoc(AppleEvent *message, AppleEvent *reply, LongInt refCon){
  157.     return OpenPrint(message, reply, refCon, RandomDotOpen1);
  158. }
  159.  
  160. /* DoPrintDoc
  161.  */
  162. static pascal OSErr DoPrintDoc(AppleEvent *message, AppleEvent *reply, LongInt refCon){
  163.     return OpenPrint(message, reply, refCon, RandomDotOpen1);
  164. }
  165.  
  166. /* DoQuitApp - 
  167.  */
  168. static pascal OSErr DoQuitApp(AppleEvent *message, AppleEvent *reply, LongInt refcon){
  169.     OSErr err;
  170.  
  171.     if ((err = MissedAEParameters(message)) != noErr){
  172.         return err;
  173.     }
  174.     localEventSelect |= bDone;
  175.     return noErr;
  176. }
  177.  
  178. static void InitAppleEventHandlers(void){
  179.     LongInt    response;
  180.  
  181.     if(noErr == Gestalt(gestaltAppleEventsAttr, &response) && 
  182.         (response & (1L << gestaltAppleEventsPresent))){
  183.  
  184.         AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, 
  185.                 NewAEEventHandlerProc(DoOpenApp), 0, FALSE);
  186.         AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
  187.                 NewAEEventHandlerProc(DoOpenDoc), 0, FALSE);
  188.         AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments,
  189.                 NewAEEventHandlerProc(DoPrintDoc), 0, FALSE);
  190.         AEInstallEventHandler(kCoreEventClass, kAEQuitApplication,
  191.                 NewAEEventHandlerProc(DoQuitApp), 0, FALSE);
  192.     }
  193. }
  194.  
  195. /* InitPopUpMenus - initialize menus used in popup
  196.  */
  197. static void InitPopUpMenus(Integer resId){
  198.     Integer     n;
  199.     Integer        **h;
  200.     SignedByte    state;
  201.  
  202.     if(NIL != (h = (Integer    **) Get1Resource('MBAR', resId))){
  203.         LoadResource((Handle) h);
  204.         state = HGetState((Handle) h);
  205.         HNoPurge((Handle) h);
  206.         HLock((Handle) h);
  207.         n = (*h)[ **h ]; 
  208.         while( NIL != GetMenu(++n) ){
  209.             /* empty */
  210.         }
  211.         HSetState((Handle) h, state);
  212.     }
  213. }
  214.  
  215.  
  216.  
  217. /* Init 
  218.  */
  219. static void Init(void){
  220.     InitGraf((Ptr) &qd.thePort);    /* initialize the toolbox */
  221.     InitFonts();
  222.     InitWindows();
  223.     InitMenus();
  224.     FlushEvents(everyEvent,0);
  225.     TEInit();
  226.     InitDialogs(0L);
  227.     InitCursor();
  228.     MaxApplZone();
  229.  
  230.     if(BetaExpired()){
  231.         Alert(kBetaDie, NIL);
  232.         ExitToShell();
  233.     }
  234.     SetMenuBar(GetNewMBar(kMBAR));
  235.     DrawMenuBar();
  236.     appResFile = CurResFile();
  237.     InitPopUpMenus(kMBAR);
  238.     AddResMenu(GetMHandle(kAppleMenu), 'DRVR');
  239.     SysEnvirons(1, &world);
  240.     if(NOT (world.hasColorQD && world.systemVersion >= 0x700)){
  241.         TellError(eNeed7AndColor);
  242.         ExitToShell();
  243.     }
  244.     if(50000L > FreeMem()){    /* check 50k free */
  245.         TellError(memFullErr);
  246.         ExitToShell();
  247.     }
  248.     InitHelpItem();
  249.     TellError(InitPreferences());
  250.     TellError(InitRandomDot());
  251.     InitAppleEventHandlers();
  252. }
  253.  
  254. /* GoHighLevelEvent - dispatch to apple event processor
  255.  */
  256. static void GoHighLevelEvent(EventRecord *theEvent){
  257.     AEProcessAppleEvent(theEvent);
  258. }
  259.  
  260.  
  261. /* GoMenuBar - 
  262.  */
  263. static void GoMenuBar(EventRecord *event){
  264.     SetCursor(&qd.arrow);
  265.     GoMenu(MenuSelect(event->where));
  266. }
  267.  
  268. /* GoKey - the keystroke handler
  269.  */
  270. static void GoKey(EventRecord *event){
  271.     WindowPtr    win;
  272.  
  273.     if(cmdKey & event->modifiers){
  274.         GoMenu(MenuKey((char) event->message));
  275.     }else if(NIL != (win = FrontWindow())){
  276.         SetPort(win);
  277.         RandomDotKey(event);
  278.     }
  279. }
  280.  
  281. /* GoAway - handle click in goAway box.
  282.  */
  283. static void GoAway(EventRecord *e, WindowPtr win){
  284.     if(TrackGoAway(win, e->where)){
  285.         DoCloseWin(win);
  286.     }
  287. }
  288.  
  289. /* GoDrag - handle drag event on title bar
  290.  */
  291. static void GoDrag(EventRecord *e, WindowPtr win){
  292.     Rect    limitR;
  293.  
  294.     limitR = (**LMGetGrayRgn()).rgnBBox;
  295.     DragWindow(win, e->where, &limitR);
  296. }
  297.  
  298. static void GoGrow(EventRecord *e, WindowPtr win){
  299.     Rect        r;
  300.     LongInt        amount;
  301.     WindowPtr    savePort;
  302.  
  303.     GetPort(&savePort);
  304.     SetPort(win);
  305.     RandomDotGrowBounds(&r);
  306.     if(0 != (amount = GrowWindow(win, e->where, &r))){
  307.         SizeWindow(win, LoWord(amount), HiWord(amount), FALSE);
  308.         InvalRect(&win->portRect);
  309.         RandomDotGrow();
  310.     }
  311.     SetPort(savePort);
  312. }
  313.  
  314. static void GoContent(EventRecord *e, WindowPtr win){
  315.     SetPort(win);
  316.     RandomDotClick(e);
  317. }
  318.  
  319. /* GoZoom - user clicked in zoom area.
  320.  */
  321. static void GoZoom(EventRecord *e, WindowPtr win, Integer sel){
  322.     WindowPtr    savePort;
  323.  
  324.     GetPort(&savePort);
  325.     SetPort(win);
  326.     if(TrackBox(win, e->where, sel)){
  327.         SetPort(win);
  328.         ZoomTheWindow((WindowPeek) win, sel, RandomDotIdealSize);
  329.         InvalRect(&win->portRect);
  330.         RandomDotGrow();
  331.     }
  332.     SetPort(savePort);
  333. }
  334.  
  335.  
  336. /* GoMouseDown - the mouse down tracker
  337.  */
  338. static void GoMouseDown(EventRecord *event, Boolean allOK){
  339.     Integer        sel;
  340.     WindowPtr    win;
  341.  
  342.     sel = FindWindow(event->where, &win);
  343.     switch(sel){
  344.     case inMenuBar:        if(allOK){ GoMenuBar(event); }            break;
  345.     case inGoAway:        if(allOK){ GoAway(event, win); }        break;
  346.     case inDrag:        GoDrag(event, win);                        break;
  347.     case inGrow:        if(allOK){ GoGrow(event, win); }        break;
  348.     case inContent:        if(allOK){ GoContent(event, win); }        break;
  349.     case inZoomIn:
  350.     case inZoomOut:        if(allOK){ GoZoom(event, win, sel); }    break;
  351.     case inSysWindow:    SystemClick(event, win);                break;
  352.     }
  353. }
  354.  
  355. /* GoIdle - 
  356.  */
  357. static void GoIdle(EventRecord *e){
  358.     WindowPtr    win;
  359.  
  360.     if(NIL != (win = FrontWindow()) && userKind == ((WindowPeek) win)->windowKind){
  361.         SetPort(win);
  362.         RandomDotIdle(e);
  363.     }
  364. }
  365.  
  366. /* ModelessFilterProc - wrapper around StdFilterProc to get the window
  367.     correct.
  368.  */
  369. static Boolean ModelessFilterProc(EventRecord *e, DialogPtr *dpp, Integer *itemp){
  370.     DialogPtr    dp;
  371.     static ModalFilterUPP    stdFilerProc = NIL;
  372.  
  373.     switch(e->what){
  374.     case updateEvt:
  375.     case activateEvt:    dp = (DialogPtr) e->message;    break;
  376.     default:            dp = FrontWindow();    break;
  377.     }
  378.     if(NIL == stdFilerProc){
  379.         GetStdFilterProc(&stdFilerProc);
  380.     }
  381.     if(CallModalFilterProc(stdFilerProc, dp, e, itemp)){
  382.         *dpp = dp;
  383.         return TRUE;
  384.     }
  385.     return FALSE;
  386. }
  387.  
  388. /* DeviceLoopUpdate - interface between devicelop and our update procedure.
  389.  */
  390. static pascal void DeviceLoopUpdate(Integer depth, Integer flags, GDHandle gdev, LongInt refCon){
  391.     RandomDotUpdate();
  392. }
  393.  
  394. /* GoUpdate - stack the port, dispatch the update
  395.  */
  396. static void GoUpdate(EventRecord *e){
  397.     WindowPtr    savePort;
  398.     static DeviceLoopDrawingUPP deviceLoopUpdate = NIL;
  399.  
  400.     if(NIL == deviceLoopUpdate){
  401.         deviceLoopUpdate = NewDeviceLoopDrawingProc(DeviceLoopUpdate);
  402.     }
  403.     GetPort(&savePort);
  404.     SetPort((WindowPtr) e->message);
  405.     BeginUpdate((WindowPtr) e->message);
  406.     DeviceLoop(qd.thePort->visRgn, deviceLoopUpdate, 0, 0);
  407.     EndUpdate((WindowPtr) e->message);
  408.     if(NIL != savePort){
  409.         SetPort(savePort);
  410.     }
  411. }
  412.  
  413. /* GoActivateEvent - activate sets the port. deactivate stacks theport.
  414.  */
  415. static void GoActivateEvent(EventRecord *e){
  416.     WindowPtr    savePort;
  417.  
  418.     if(userKind == ((WindowPeek) e->message)->windowKind){
  419.         GetPort(&savePort);
  420.         SetPort((WindowPtr) e->message);
  421.         if(activeFlag & e->modifiers){
  422.             RandomDotActivate();
  423.         }else{
  424.             RandomDotDeactivate();
  425.             if(NIL != savePort){
  426.                 SetPort(savePort);
  427.             }
  428.         }
  429.     }
  430. }
  431.  
  432. /* GoOSEvent - 
  433.  */
  434. static void GoOSEvent(EventRecord *e){
  435.     WindowPtr    win;
  436.  
  437.     switch((e->message >> 12) & 0xFF){
  438.     case suspendResumeMessage:
  439.         if(resumeFlag & e->modifiers){
  440.             if(NIL != (win = FrontWindow()) && userKind == ((WindowPeek) win)->windowKind){
  441.                 SetPort(win);
  442.                 RandomDotActivate();
  443.             }
  444.         }else{
  445.             if(NIL != (win = FrontWindow()) && userKind == ((WindowPeek) win)->windowKind){
  446.                 SetPort(win);
  447.                 RandomDotDeactivate();
  448.             }
  449.         }
  450.         break;
  451.     }
  452. }
  453.  
  454.  
  455.  
  456. /* GoEvent - main event dispatcher.
  457.  */
  458. static void GoEvent(EventRecord *e){
  459.     DialogPtr    dp;
  460.     Integer        item;
  461.  
  462.     if(IsDialogEvent(e) && 
  463.         (ModelessFilterProc(e, &dp, &item) || 
  464.         DialogSelect(e, &dp, &item)) &&
  465.         NIL != dp){
  466. #if 0
  467.             if(gRandomDotConfig == dp){
  468.                 DoRandomDotConfigItem(item);
  469.             }
  470. #endif
  471.             return;
  472.     }
  473.     switch(e->what){
  474.     case nullEvent:            GoIdle(e);            break;
  475.     case mouseDown:            GoMouseDown(e, TRUE);    break;
  476.     case autoKey:            
  477.     case keyDown:            GoKey(e);            break;
  478.     case updateEvt:            GoUpdate(e);        break;
  479.     case activateEvt:        GoActivateEvent(e);    break;
  480.     case osEvt:                GoOSEvent(e);        break;
  481.     case kHighLevelEvent:    GoHighLevelEvent(e);    break;
  482.     default:                break;
  483.     }
  484. }
  485.  
  486. /* DialogOnTopGoEvent - call this when we can't handle keydowns or update events.
  487.     and the only legal mouse events are window drags.
  488.  */
  489. void DialogOnTopGoEvent(EventRecord *e){
  490.     switch(e->what){
  491.     case nullEvent:            GoIdle(e);            break;
  492.     case mouseDown:            GoMouseDown(e, FALSE);        break;
  493.     case activateEvt:        GoActivateEvent(e);    break;
  494.     case osEvt:                GoOSEvent(e);        break;
  495.     case kHighLevelEvent:    GoHighLevelEvent(e);    break;
  496.     default:                break;
  497.     }
  498. }
  499.  
  500.  
  501. /* HandleEvents - 
  502.  */
  503. void HandleEvents(void){
  504.     EventRecord e;
  505.  
  506.     if(0 != localEventSelect){
  507.         if(localEventSelect & bDone){
  508.             DoQuit();
  509.         }
  510.         if(localEventSelect & bDoOpenCommandOnce){
  511.             localEventSelect &= ~bDoOpenCommandOnce;
  512.             DoOpen();
  513.         }
  514.         if(localEventSelect & bDoHelpCommandOnce){
  515.             localEventSelect &= ~bDoHelpCommandOnce;
  516.             DoHelp();
  517.         }
  518.     }
  519.     WaitNextEvent(everyEvent, &e, NIL, 0);
  520.     GoEvent(&e);    /* allow null event processing */
  521. }
  522.  
  523.  
  524. /* main
  525.  */
  526. main(){
  527.     Init();
  528.     for(;;){
  529.         HandleEvents();
  530.     }
  531.     return 0;
  532. }
  533.